#if (FEATURE_MODE == 0)
/**
 @file ctc_greatbel_dot1ae_cli.c

 @date 2017-08-22

 @version v2.0

---file comments----
*/

/****************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "ctc_dot1ae_cli.h"
#include "ctc_cli.h"
#include "ctc_cli_common.h"
#include "ctc_error.h"
#include "ctc_api.h"
#include "ctcs_api.h"
#include "ctc_debug.h"
#include "ctc_api.h"
#include "ctcs_api.h"


mac_addr_t  mac_da_addr = {0};
mac_addr_t  mac_da_addr_mask = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
mac_addr_t  mac_sa_addr = {0};
mac_addr_t  mac_sa_addr_mask = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
ipv6_addr_t ipv6_da_addr = {0};
ipv6_addr_t ipv6_da_addr_mask = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
ipv6_addr_t ipv6_sa_addr = {0};
ipv6_addr_t ipv6_sa_addr_mask = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};

#define CTC_CLI_DOT1AE_KEY_FIELD_STR "\
  ip-sa VALUE \
| ip-da VALUE \
| ipv6-sa VALUE \
| ipv6-da VALUE \
| ip-protocol VALUE \
| l4-dst-port VALUE \
| l4-src-port VALUE \
| sci  VALUE \
| svlan  VALUE \
| cvlan  VALUE \
| gport VALUE \
| eth-type VALUE \
| spi VALUE \
"

#define CTC_CLI_DOT1AE_KEY_FIELD_DESC \
"source ipv4 address ", "value", \
"destination ipv4 address ", "value",\
"source ipv6 address ", "value",\
"destination ipv6 address ", "value",\
"ip protocol ", "value", \
"l4 dest port ", "value", \
"l4 source port ", "value", \
"sci ", "value",\
"svlan ", "value", \
"cvlan ", "value", \
"gport ", "value", \
"eth-type ", "ether type", \
"spi ", "value"



struct sys_dot1ae_show_entry_info_s
{
    uint8 type ;
	uint8 dir;
	uint8 key_type;
	uint8 detail;
	uint32 entry_id;
};
typedef struct sys_dot1ae_show_entry_info_s sys_dot1ae_show_entry_info_t;




#define CTC_CLI_DOT1AE_KEY_FIELD_SET(key_field, arg, start)\
do{\
  index = CTC_CLI_GET_ARGC_INDEX("ip-sa");\
    if (0xFF != index) \
    {\
        key_field->type = CTC_FIELD_KEY_IP_SA;\
            CTC_CLI_GET_IPV4_ADDRESS("ipsa", key_field->data, argv[index + 1]);\
        arg;\
    }\
    index = CTC_CLI_GET_ARGC_INDEX("ip-da");\
    if (0xFF != index) \
    {\
        key_field->type = CTC_FIELD_KEY_IP_DA;\
            CTC_CLI_GET_IPV4_ADDRESS("ipda", key_field->data, argv[index + 1]);\
        arg;\
    }\
    index = CTC_CLI_GET_ARGC_INDEX("ipv6-sa");\
    if (0xFF != index) \
    {\
        key_field->type = CTC_FIELD_KEY_IPV6_SA;\
            CTC_CLI_GET_IPV6_ADDRESS("ip-sa", ipv6_sa_addr, argv[index + 1]);               \
            ipv6_sa_addr[0] = sal_htonl(ipv6_sa_addr[0]);                                 \
            ipv6_sa_addr[1] = sal_htonl(ipv6_sa_addr[1]);                                 \
            ipv6_sa_addr[2] = sal_htonl(ipv6_sa_addr[2]);                                 \
            ipv6_sa_addr[3] = sal_htonl(ipv6_sa_addr[3]);                                 \
            key_field->ext_data = ipv6_sa_addr;    \
        arg;\
    }\
    index = CTC_CLI_GET_ARGC_INDEX("ipv6-da");\
    if (0xFF != index) \
    {\
        key_field->type = CTC_FIELD_KEY_IPV6_DA;\
            CTC_CLI_GET_IPV6_ADDRESS("ip-da", ipv6_da_addr, argv[index + 1]);               \
            ipv6_da_addr[0] = sal_htonl(ipv6_da_addr[0]);                                 \
            ipv6_da_addr[1] = sal_htonl(ipv6_da_addr[1]);                                 \
            ipv6_da_addr[2] = sal_htonl(ipv6_da_addr[2]);                                 \
            ipv6_da_addr[3] = sal_htonl(ipv6_da_addr[3]);                                 \
            key_field->ext_data = ipv6_da_addr;    \
        arg;\
    }\
    index = CTC_CLI_GET_ARGC_INDEX("l4-dst-port");\
    if (0xFF != index) \
    {\
        key_field->type = CTC_FIELD_KEY_L4_DST_PORT;\
            CTC_CLI_GET_UINT32("value", key_field->data, argv[index + 1]);\
        arg;\
    }\
    index = CTC_CLI_GET_ARGC_INDEX("l4-src-port");\
    if (0xFF != index) \
    {\
        key_field->type = CTC_FIELD_KEY_L4_SRC_PORT;\
            CTC_CLI_GET_UINT32("value", key_field->data, argv[index + 1]);\
        arg;\
    }\
    index = CTC_CLI_GET_ARGC_INDEX("ip-protocol");\
    if (0xFF != index) \
    {\
        key_field->type = CTC_FIELD_KEY_IP_PROTOCOL;\
            CTC_CLI_GET_UINT32("value", key_field->data, argv[index + 1]);\
        arg;\
    }\
	index = CTC_CLI_GET_ARGC_INDEX("sci");\
    if (0xFF != index)\
     {\
         key_field->type = CTC_FIELD_KEY_DOT1AE_SCI;\
         sal_sscanf(argv[index+1], "%16"PRIx64,(uint64*)sci);\
         for (i=0;i<sizeof(sci);i++)\
         {\
             sci_tmp[sizeof(sci)-1-i] = sci[i];\
         }\
         key_field->ext_data= (void*)&sci_tmp[0];\
         arg;\
     }\
    index = CTC_CLI_GET_ARGC_INDEX("svlan");\
    if (0xFF != index) \
    {\
        key_field->type = CTC_FIELD_KEY_SVLAN_ID;\
            CTC_CLI_GET_UINT32("value", key_field->data, argv[index + 1]);\
        arg;\
    }\
    index = CTC_CLI_GET_ARGC_INDEX("cvlan");\
    if (0xFF != index) \
    {\
        key_field->type = CTC_FIELD_KEY_CVLAN_ID;\
            CTC_CLI_GET_UINT32("value", key_field->data, argv[index + 1]);\
        arg;\
    }\
    index = CTC_CLI_GET_ARGC_INDEX("gport");\
    if (0xFF != index) \
    {\
        key_field->type = CTC_FIELD_KEY_PORT;\
            CTC_CLI_GET_UINT32("value", key_field->data, argv[index + 1]);\
        arg;\
    }\
    index = CTC_CLI_GET_ARGC_INDEX("eth-type");\
    if (0xFF != index) \
    {\
        key_field->type = CTC_FIELD_KEY_ETHER_TYPE;\
            CTC_CLI_GET_UINT32("value", key_field->data, argv[index + 1]);\
        arg;\
    }\
    index = CTC_CLI_GET_ARGC_INDEX("spi");\
    if (0xFF != index) \
    {\
        key_field->type = CTC_FIELD_KEY_DOT1AE_SPI;\
            CTC_CLI_GET_UINT16("spi", key_field->data, argv[index + 1]);\
        arg;\
    }\
}while(0)

extern int32
sys_usw_dot1ae_show_status(uint8 lchip);
extern int32
sys_usw_dot1ae_show_entry(uint8 lchip, sys_dot1ae_show_entry_info_t* param);
extern int32
sys_usw_dot1ae_get_entry(uint8 lchip,uint32 entry_id);
CTC_CLI(ctc_cli_usw_show_dot1ae_sec_chan,
        ctc_cli_usw_show_dot1ae_sec_chan_cmd,
        "show dot1ae status",
        CTC_CLI_SHOW_STR,
        "Dot1AE",
        "Dot1AE overall status"
        )
{
    int32  ret = 0;

    ret = sys_usw_dot1ae_show_status(g_api_lchip);

    if (ret < 0)
    {
        ctc_cli_out("%% ret =%d, %s\n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}



CTC_CLI(ctc_cli_usw_add_dot1ae_entry,
        ctc_cli_usw_add_dot1ae_entry_cmd,
        "dot1ae add entry ENTRY_ID key-type (l2-key|mac-key|ipv4-key|ipv6-key|spi-key) key-field {" CTC_CLI_DOT1AE_KEY_FIELD_STR "}(chan-id CHANNELID)(dir DIR|)",
        "Dot1AE",
        "Add",
        "Entry",
        "Value",
        "Key type",
        "L2 ext key",
        "Mac key",
        "Ipv4 key",
        "Ipv6 key",
        "Spi key",
        "Key_field",
        CTC_CLI_DOT1AE_KEY_FIELD_DESC,
        "Dot1ae channel id",
        "VALUE",
        "Direction",
        "<0:Ingress,1:Egress>")
{

    int32  ret = 0;
    uint8  index = 0;
    uint8 arg_cnt = 0;
    uint32 field_cnt = 0;
    uint8  sci[8] = {0};
    uint8  sci_tmp[8] = {0};
    uint8 i=0;
    ctc_dot1ae_entry_t dot1ae_entry;
    ctc_field_key_t key_field[CTC_CLI_ACL_KEY_FIELED_GREP_NUM];
    ctc_field_key_t* p_field = &key_field[0];
    sal_memset(key_field, 0, CTC_CLI_ACL_KEY_FIELED_GREP_NUM * sizeof(ctc_field_key_t));
    sal_memset(&dot1ae_entry, 0, sizeof(ctc_dot1ae_entry_t));

    CTC_CLI_GET_UINT32("entry-id", dot1ae_entry.entry_id, argv[0]);

    CTC_CLI_DOT1AE_KEY_FIELD_SET(p_field, CTC_CLI_ACL_KEY_ARG_CHECK(arg_cnt, CTC_CLI_ACL_KEY_FIELED_GREP_NUM, p_field), 0);
    field_cnt = arg_cnt;
    dot1ae_entry.field_cnt = field_cnt;
    dot1ae_entry.p_field_key = key_field;

    index = CTC_CLI_GET_ARGC_INDEX("l2-key");
    if (index != 0xFF)
    {
        dot1ae_entry.key_type |= CTC_DOT1AE_KEY_L2;
    }
    index = CTC_CLI_GET_ARGC_INDEX("mac-key");
    if (index != 0xFF)
    {
        dot1ae_entry.key_type |= CTC_DOT1AE_KEY_MACSEC;
    }
    index = CTC_CLI_GET_ARGC_INDEX("ipv4-key");
    if (index != 0xFF)
    {
        dot1ae_entry.key_type |= CTC_DOT1AE_KEY_IPV4;
    }
    index = CTC_CLI_GET_ARGC_INDEX("ipv6-key");
    if (index != 0xFF)
    {
        dot1ae_entry.key_type |= CTC_DOT1AE_KEY_IPV6;
    }
	index = CTC_CLI_GET_ARGC_INDEX("spi-key");
    if (index != 0xFF)
    {
        dot1ae_entry.key_type |= CTC_DOT1AE_KEY_SPI;
    }
    index = CTC_CLI_GET_ARGC_INDEX("dir");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT8_RANGE("dir", dot1ae_entry.dir, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
    }
    index = CTC_CLI_GET_ARGC_INDEX("chan-id");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT32_RANGE("chan id", dot1ae_entry.chan_id, argv[index + 1], 0, CTC_MAX_UINT32_VALUE);
    }

    if(g_ctcs_api_en)
     {
         ret =  ctcs_dot1ae_add_entry(g_api_ldev, &dot1ae_entry);
     }
     else
     {
         ret =  ctc_dot1ae_add_entry(&dot1ae_entry);
     }
     if (ret < 0)
     {
         ctc_cli_out("%% ret =%d, %s\n", ret, ctc_get_error_desc(ret));
         return CLI_ERROR;
     }

    return ret;
}

CTC_CLI(ctc_cli_usw_remove_dot1ae_entry,
        ctc_cli_usw_remove_dot1ae_entry_cmd,
        "dot1ae remove entry ENTRY_ID",
        "Dot1AE",
        "Remove",
        "Entry",
        "Value")
{
     int32 ret=0;
     uint32 entry_id=0;
     CTC_CLI_GET_UINT32("entry-id", entry_id, argv[0]);

    if(g_ctcs_api_en)
     {
         ret =  ctcs_dot1ae_remove_entry(g_api_ldev, entry_id);
     }
     else
     {
         ret =  ctc_dot1ae_remove_entry(entry_id);
     }
     if (ret < 0)
     {
         ctc_cli_out("%% ret =%d, %s\n", ret, ctc_get_error_desc(ret));
         return CLI_ERROR;
     }


    return 0;
}

CTC_CLI(ctc_cli_usw_show_dot1ae_entry_info,
        ctc_cli_usw_show_dot1ae_entry_info_cmd,
        "show dot1ae entry-info (all | entry-id ENTRY_ID) \
        (type (decrypt-mac |decrypt-ipv4 | decrypt-ipv6 | decrypt-l2 | encrypt-mac |encrypt-ipv4 | encrypt-ipv6)|) \
         (detail|)",
        CTC_CLI_SHOW_STR,
        "Dot1ae module",
        "Entry info",
        "All entries",
        "By entry",
        "Entry id",
        "Entry type",
        "Dot1ae rx macsec key, including p2mp and wansec",
        "Dot1ae rx ipv4 key",
        "Dot1ae rx ipv6 key",
        "Dot1ae rx l2 key",
        "Dot1ae tx macsec key, including p2mp and wansec",
        "Dot1ae tx ipv4 key",
        "Dot1ae tx ipv6 key",
        "Detail")
{
    int32 ret = CLI_SUCCESS;
    uint8 index = 0;
	sys_dot1ae_show_entry_info_t entry_param;
	sal_memset(&entry_param, 0, sizeof(sys_dot1ae_show_entry_info_t));


    index = CTC_CLI_GET_ARGC_INDEX("all");
    if (INDEX_VALID(index))
    {
        entry_param.type = 0;
    }
    index = CTC_CLI_GET_ARGC_INDEX("entry-id");
    if (INDEX_VALID(index))
    {
        entry_param.type = 1;
        CTC_CLI_GET_UINT32("entry id", entry_param.entry_id, argv[index + 1]);
    }

	index = CTC_CLI_GET_ARGC_INDEX("type");
		if (INDEX_VALID(index))
        {
            if CTC_CLI_STR_EQUAL_ENHANCE("decrypt-mac", index + 1)
            {
                entry_param.key_type = CTC_DOT1AE_KEY_MACSEC;
				entry_param.dir = CTC_INGRESS;
            }
            else if CTC_CLI_STR_EQUAL_ENHANCE("decrypt-ipv4", index + 1)
            {
                entry_param.key_type = CTC_DOT1AE_KEY_IPV4;
                entry_param.dir = CTC_INGRESS;
            }
            else if CTC_CLI_STR_EQUAL_ENHANCE("decrypt-ipv6", index + 1)
            {
                entry_param.key_type = CTC_DOT1AE_KEY_IPV6;
                entry_param.dir = CTC_INGRESS;
            }
            else if CTC_CLI_STR_EQUAL_ENHANCE("decrypt-l2", index + 1)
            {
                entry_param.key_type = CTC_DOT1AE_KEY_L2;
                entry_param.dir = CTC_INGRESS;
            }
                  
            if CTC_CLI_STR_EQUAL_ENHANCE("encrypt-mac", index + 1)
            {
                entry_param.key_type = CTC_DOT1AE_KEY_MACSEC;
                entry_param.dir = CTC_EGRESS;
            }
            else if CTC_CLI_STR_EQUAL_ENHANCE("encrypt-ipv4", index + 1)
            {
                entry_param.key_type = CTC_DOT1AE_KEY_IPV4;
                entry_param.dir = CTC_EGRESS;
            }
            else if CTC_CLI_STR_EQUAL_ENHANCE("encrypt-ipv6", index + 1)
            {
                entry_param.key_type = CTC_DOT1AE_KEY_IPV6;
                entry_param.dir = CTC_EGRESS;
            }
        }
        else
        {
            entry_param.key_type = CTC_DOT1AE_KEY_MAX;
        }

    index = CTC_CLI_GET_ARGC_INDEX("detail");
    if (INDEX_VALID(index))
    {
        entry_param.detail = 1;
    }

    ret = sys_usw_dot1ae_show_entry(g_api_lchip,&entry_param);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return 0;
}


int32
ctc_usw_dot1ae_cli_init(void)
{
    install_element(CTC_SDK_MODE, &ctc_cli_usw_show_dot1ae_sec_chan_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_usw_add_dot1ae_entry_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_usw_remove_dot1ae_entry_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_usw_show_dot1ae_entry_info_cmd);

    return CLI_SUCCESS;
}

int32
ctc_usw_dot1ae_cli_deinit(void)
{
    uninstall_element(CTC_SDK_MODE, &ctc_cli_usw_show_dot1ae_sec_chan_cmd);
    uninstall_element(CTC_SDK_MODE, &ctc_cli_usw_add_dot1ae_entry_cmd);
    uninstall_element(CTC_SDK_MODE, &ctc_cli_usw_remove_dot1ae_entry_cmd);
    uninstall_element(CTC_SDK_MODE, &ctc_cli_usw_show_dot1ae_entry_info_cmd);

    return CLI_SUCCESS;
}

#endif

